import numpy as np 
import tensorflow as tf 
import cv2 as cv 
import os
import matplotlib.pyplot as plt
import sklearn
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt 
from keras.layers import Input,Dense,Activation,Dropout,MaxPooling2D,Softmax,Conv2D,Flatten,BatchNormalization,Average,Permute,Reshape
from keras.models import Model,Sequential,load_model
from keras.callbacks import ModelCheckpoint
from keras.preprocessing.image import img_to_array,load_img
from keras import optimizers
from keras.utils.generic_utils import get_custom_objects
import keras.backend as K 
from keras.callbacks import LearningRateScheduler
from PIL import Image
from resnet import resnet_model,conv_block,identity_block
import random
from resnet import *


def read_img(imageName):
    # im=Image.open(imageName).convert('L')#这里是转换成了灰度图，之后看看能不能搞个彩图把
    im=cv.imread(imageName)
#     im=cv.resize(im,(112,112))#resnet不用了
    im=cv.resize(im,(224,224))
    im=np.array(im)#resnet用的
    im=im.swapaxes(0,2)#resnet用的


    # im=np.expand_dims(im,axis=0)
    # im=np.expand_dims(im,axis=0)
    # im=tf.image.resize(im,(500,500))

    data=np.array(im)

    return data

def read_dir_image(path):
    for fn in os.listdir(path):
        fd=os.path.join(path,fn)
        images.append(read_img(fd))


def read_label(path):
    x=np.loadtxt(path+'/second_152.txt')
    # print(x)
    return x


def plot_result(results):

    loss = results.history['loss']
    val_loss = results.history['val_loss']

    epochs = range(1, len(loss) + 1)

    plt.plot(epochs, loss, 'r', label = 'Training loss')
    plt.plot(epochs, val_loss, 'b', label = 'Validation loss')
    plt.title('Training And Validation Loss')
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.legend()
    plt.show()

    plt.clf()

    acc = results.history['acc']
    val_acc = results.history['val_acc']

    plt.plot(epochs, acc, 'r', label = 'Training acc')
    plt.plot(epochs, val_acc, 'b', label = 'Validation acc')
    plt.title('Training And Validation Accuracy')
    plt.xlabel('Epochs')
    plt.ylabel('Accuracy')
    plt.legend()
    plt.show()


# def nm_model():
#     model=nn_model()
#     modell=Sequential()
#     modell.add(([model.get_layer('dense_6').output,model.get_layer('dense_6').output]))
#     modell.add(Dense(160,activation='tanh'))
#     modell.compile(optimizer="sgd",loss="mse",metrics=["accuracy"])
#     return modell

# def nn_model():
#     model=Sequential()
#     model.add(Dense(512,activation='elu',input_shape=(162,)))
#     model.add(Dropout(0.2))
#     model.add(Dense(512,activation='selu'))
#     model.add(Dropout(0.3))
#     model.add(Dense(512,activation='elu'))
#     model.add(Dropout(0.4))
#     model.add(Dense(512,activation='tanh'))
#     model.add(Dropout(0.5))
#     model.add(Dense(512,activation='tanh'))
#     model.add(Dropout(0.6))
#     model.add(Dense(160,activation='tanh'))
#     model.summary()
#     model.compile(optimizer="sgd",loss="mse",metrics=["accuracy"])
#     return model

model_input=Input(shape=(162,))
model_input_img=Input(shape=((3,224,224)))
#test========================================
def nn_model(model_input):
    x=Dense(512,activation='elu')(model_input)
    x=Dropout(0.2)(x)
    x=Dense(512,activation='selu')(x)
    x=Dropout(0.3)(x)
    x=Dense(512,activation='elu')(x)
    x=Dropout(0.4)(x)
    x=Dense(512,activation='tanh')(x)
    x=Dropout(0.5)(x)
    x=Dense(512,activation='tanh')(x)
    x=Dropout(0.6)(x)
    x=Dense(152,activation='tanh')(x)
    model=Model(model_input,x,name='nn_model_1')
    model.compile(optimizer="sgd",loss="mse",metrics=["accuracy"])
    return model

def nn_model_2(model_input):
    x=Dense(512,activation='elu')(model_input)
    x=Dropout(0.2)(x)
    x=Dense(512,activation='selu')(x)
    x=Dropout(0.3)(x)
    x=Dense(512,activation='elu')(x)
    x=Dropout(0.4)(x)
    x=Dense(512,activation='tanh')(x)
    x=Dropout(0.5)(x)
    x=Dense(512,activation='tanh')(x)
    x=Dropout(0.6)(x)
    x=Dense(152,activation='tanh')(x)
    model=Model(model_input,x,name='nn_model_2')
    model.compile(optimizer="sgd",loss="mse",metrics=["accuracy"])
    return model


def essemble(input_model,input_model_1):
    first=nn_model(input_model)
    second=nn_model_2(input_model_1)

    models=[first,second]
    return models

def essemble_after(models,model_input,model_input_1):
    
    input_2=Input(shape=((3,224,224)))
    input_1=Input(shape=(162,))
    outputs=[model.output for model in models]#这边千万千万不要加[0]，好像是为了三个模型合并采用的，或者完全就是错了

#     y=Average()(outputs)
    y=K.concatenate(outputs)
#     y=Flatten()(outputs)
    # y=Reshape((160,))(y)
    # x=Dense(160,activation='tanh')(outputs)
    
    model=Model([model_input,model_input_1],y,name='essemble')###这里出了问题！！！
    model.compile(optimizer="sgd",loss="mse",metrics=["accuracy"])
    return model
#test========================================



# def read_label(path):
#     x=np.loadtxt(path+'\\second_152.txt')
#     # print(x)
#     return x

def read_input(path):
    x=np.load(path+'\\merge_train_152_81.npy')
    return x

x=np.array(read_input('D:\\facial\\neural_network'))
y=np.array(read_label('D:'))
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.30, random_state=30)
x_train=x_train.reshape((len(x_train),162))
x_test=x_test.reshape((len(x_test),162))



images=[]
read_dir_image("D:/facial/premiere/ayan/training/")
x_img=np.array(images)
y_img=np.array(read_label("D:"))
x_train_img, x_test_img, y_train_img, y_test_img = train_test_split(x_img, y_img, test_size=0.30, random_state=30)





# print(x_train)
# print(x_test)
# print(y_train)
# print(y_test)
# model=nn_model()
# model=nm_model()
# results=model.fit(x_train,y_train,epochs=10000,batch_size=30,validation_data=(x_test,y_test))

# model.save('FCN_model.h5')


# model=nn_model(model_input)
# model_1=nn_model_2(model_input)


# model_2=essemble(model_input,model_input)

# filepath="dense_weights-best.hdf5"
# checkpoint = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=True,mode='min')
# callbacks_list = [checkpoint]

# pair_1=[model,model_1]
# model_2=essemble_after(pair_1,model_input)

model=load_model('dense_my_model.h5')
# results=model.fit(x_train,y_train,epochs=5,batch_size=30,validation_data=(x_test,y_test))

model_1=load_model('my_model_res_1500_152_nice.h5')
# result_1=model_1.fit(x_train_img,y_train_img,epochs=15,batch_size=10,validation_data=(x_test_img,y_test_img))


pair_1=[model,model_1]
model_2=essemble_after(pair_1,model_input,model_input_img)

# model.save('dense_my_model.h5')
# results_1=model_1.fit(x_train,y_train,epochs=1000,batch_size=30,validation_data=(x_test,y_test))
# results_2=model_2.fit([x_train,x_train_img],[y_train,y_train_img],epochs=1000,batch_size=10,validation_data=([x_test,x_test_img],[y_test,y_test_img]))
results_2=model_2.fit([x_train_img,x_train],[y_train_img,y_train],epochs=1000,batch_size=10,validation_data=([x_test_img,x_test],[y_test_img,y_test]))

plot_result(results_2)
# plot_result(results_1)
# plot_result(results_2)
